from datetime import datetime
import asyncio

from dataclasses import dataclass, field
from typing import Type, Callable, Dict, List, Union, Awaitable

@dataclass  # type: ignore[arg-type]
class Event:
    """基础事件类"""
    timestamp: datetime = field(default_factory=datetime.now)

@dataclass
class MarketDataEvent(Event):
    """市场数据事件"""
    symbol: str = ""
    data: dict = field(default_factory=dict)
    # 继承父类Event的timestamp字段（已带默认值）

@dataclass  # type: ignore[arg-type]
class SignalEvent(Event):
    """信号事件"""
    strategy: str = ""
    signals: dict = field(default_factory=dict)
    # 继承父类Event的timestamp字段

class EventBus:
    """事件总线"""
    
    def __init__(self):
        self._handlers: Dict[Type[Event], List[Callable]] = {}
        self._async_handlers: Dict[Type[Event], List[Callable]] = {}
        self._filters: Dict[Type[Event], List[Callable]] = {}
        self._priorities: Dict[Type[Event], Dict[Callable, int]] = {}

    def add_filter(self, event_type: Type[Event], filter_fn: Callable) -> None:
        """添加事件过滤器"""
        if event_type not in self._filters:
            self._filters[event_type] = []
        self._filters[event_type].append(filter_fn)

    def set_priority(self, event_type: Type[Event], handler: Callable, priority: int) -> None:
        """设置事件处理优先级"""
        if event_type not in self._priorities:
            self._priorities[event_type] = {}
        self._priorities[event_type][handler] = priority

    async def publish_async(self, event: Event) -> None:
        """异步发布事件"""
        max_retries = 3
        backoff_factor = 0.5
        
        for attempt in range(max_retries):
            try:
                # 应用事件过滤器
                if type(event) in self._filters:
                    if any(not filter_fn(event) for filter_fn in self._filters[type(event)]):
                        return
                
                # 处理同步handler
                if type(event) in self._handlers:
                    handlers = self._handlers[type(event)]
                    # 按优先级排序
                    if type(event) in self._priorities:
                        handlers = sorted(handlers,
                                       key=lambda h: self._priorities[type(event)].get(h, 0),
                                       reverse=True)
                    for handler in handlers:
                        handler(event)
                
                # 处理异步handler
                if type(event) in self._async_handlers:
                    handlers = self._async_handlers[type(event)]
                    # 按优先级排序
                    if type(event) in self._priorities:
                        handlers = sorted(handlers,
                                       key=lambda h: self._priorities[type(event)].get(h, 0),
                                       reverse=True)
                    await asyncio.gather(*(handler(event) for handler in handlers))
                return
            except (ConnectionError, TimeoutError) as e:
                if attempt == max_retries - 1:
                    raise
                await asyncio.sleep(backoff_factor * (2 ** attempt))
                await self._reconnect_async()

    def publish(self, event: Event) -> None:
        """同步发布事件"""
        loop = asyncio.get_event_loop()
        if loop.is_running():
            loop.create_task(self.publish_async(event))
        else:
            loop.run_until_complete(self.publish_async(event))

    async def subscribe_async(self, event_type: Type[Event], handler: Callable) -> None:
        """异步订阅事件"""
        if event_type not in self._async_handlers:
            self._async_handlers[event_type] = []
        self._async_handlers[event_type].append(handler)
                
    async def _reconnect_async(self):
        """异步重连机制"""
        max_retries = 5
        base_delay = 1.0
        
        for retry in range(max_retries):
            try:
                # 模拟实际重连逻辑
                return
            except ConnectionError as e:
                if retry == max_retries - 1:
                    raise ConnectionError(f"重连失败 ({max_retries}次尝试)") from e
                await asyncio.sleep(base_delay * (2 ** retry))

    def _reconnect(self):
        """同步重连机制"""
        return asyncio.run(self._reconnect_async())

    def subscribe(self, event_type: Type[Event], handler: Callable) -> None:
        """同步订阅事件"""
        if event_type not in self._handlers:
            self._handlers[event_type] = []
        self._handlers[event_type].append(handler)

    async def unsubscribe_async(self, event_type: Type[Event], handler: Callable) -> None:
        """异步取消订阅"""
        if event_type in self._async_handlers:
            self._async_handlers[event_type].remove(handler)

    def unsubscribe(self, event_type: Type[Event], handler: Callable) -> None:
        """同步取消订阅"""
        if event_type in self._handlers:
            self._handlers[event_type].remove(handler)
        if event_type in self._async_handlers:
            self._async_handlers[event_type].remove(handler)